#ifndef D3D_H
#define D3D_H

//Direct3D libs
#pragma comment (lib, "d3d9.lib")
#pragma comment (lib, "d3dx9.lib")

#include <d3d9.h>
#include <d3dx9.h>

#include <string>
#include <vector>

class SceneNode;

#define SIMPLE_VERTEX_FORMAT (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0))

typedef struct simple_vertex 
{
	float x, y, z;
	unsigned long color;
	float tu, tv, tw;
} SIMPLE_VERTEX;

long InitD3D();
long DestroyD3D();

class Device {
public:
  long createWindowed(HWND window, float rwidth = 1.0, float rheight = 1.0);
  long createFullscreen(HWND window, unsigned long width = 800, unsigned long height = 600, unsigned long refresh = 75, float rwidth = 1.0, float rheight = 1.0);
  void set();
  void destroy();
  long beginScene();
  void endScene();
  void resize(float width, float height);
  HRESULT reset(long width, long height);
  unsigned long deviceHeight();
  unsigned long deviceWidth();

  long createFont(const char * name, unsigned long size);
  long loadTexture(LPDIRECT3DTEXTURE9 * texture, const char * file);
  void loadShader(LPD3DXEFFECT * shader, const char * file);
  void createEmptyTexture(LPDIRECT3DTEXTURE9 * texture, UINT width, UINT height);

  void setView(float x, float y);
  void setColor(unsigned long color);
  void setBackgroundColor(unsigned long color);
  unsigned long getColor();
  void setTexture(LPDIRECT3DTEXTURE9 texture);
  LPDIRECT3DTEXTURE9 getTexture();

  void drawRect(float x, float y, float width, float height, float theta = 0.0f, float tu = 0.0f, float tv = 0.0f, float twidth = 1.0f, float theight = 1.0f);
  int  drawText(const char * text, long font, long x, long y, long width, long height, unsigned long color = 0xffffffff, unsigned long format = DT_SINGLELINE);
  void drawLine(float x1, float y1, float x2, float y2);

  void screenShot(std::string name);

  HRESULT pushWorldMatrix(const D3DXMATRIX * matrix);
  HRESULT popWorldMatrix();

  SceneNode * read[2];
  CRITICAL_SECTION cs_switch;
  CRITICAL_SECTION cs_buffer[2];
  unsigned long timestamp[2];
  unsigned long laststamp;

protected:
  float _rwidth;
  float _rheight;
  D3DPRESENT_PARAMETERS _d3dpp;
  D3DDISPLAYMODE _current_mode;
  long create(HWND window, float rwidth, float rheight);
  LPDIRECT3DDEVICE9 _pD3Ddev;
  D3DXMATRIX _projection;
  D3DXMATRIX _view;
  LPD3DXMATRIXSTACK _world;
  LPDIRECT3DVERTEXBUFFER9 _rect_verts;
  LPDIRECT3DVERTEXBUFFER9 _line_verts;
  std::vector<LPD3DXFONT> _fonts;
  unsigned long _background_color;
};


long AddDevice();
void RemoveDevice(long device);
Device * GetDevice(long device);


#endif
